package com.prj.ufdm.demo.tutorial.thread;

/**
    * 通过 ThreadLocal 获取 多个线程的独立序列 （A、B 两个线程通过操作同一个实例变量，分别打印出：1,2,3,4,5。。）  
  * TTLSeqNum 普通实现队列
  * TTLThreadLocalSeqNum 通过 ThreadLocal 实现队列
    *  如果不通过 ThreadLocal ，多个线程操作同一个对象，对象中的实例变量是同一个，线程之间共享
    *  使用ThreadLocal，线程之间的变量是独享的
  * 
  * @author Administrator
  *
  */
public class TestThreadLocal {
	
	public static void main(String []args){
		
//		TTLSeqNum seqNum = new TTLSeqNum();
		
		TTLThreadLocalSeqNum seqNum = new  TTLThreadLocalSeqNum();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int i=0;i<5;i++) {
				    System.out.println("threadA[" + Thread.currentThread().getName() + "] sn[" + seqNum.getNextNum() + "]");
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int i=0;i<3;i++) {
				    System.out.println("threadB[" + Thread.currentThread().getName() + "] sn[" + seqNum.getNextNum() + "]");
				}
			}
		}).start();
    }
}

/**
 * 
  *  普通类获取序列
 * @author Administrator
 */
class TTLSeqNum {
	
	Integer seqNum = 0;
	
	// 获取下一个序列值
	public synchronized Integer getNextNum() {
		seqNum = seqNum + 1;
		return seqNum;
	}

}

/**
  *  通过 ThreadLocal 获取序列
 * @author Administrator
 */
class TTLThreadLocalSeqNum {

	// 通过匿名内部类覆盖 ThreadLocal 的initialValue()方法，指定初始值
	private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {
		@Override
		protected Integer initialValue() {
			return 0;
		}
	};
	
	// 获取下一个序列值
	public synchronized Integer getNextNum() {
		seqNum.set(seqNum.get() + 1);
		return seqNum.get();
	}

}


